const redis = require('redis');
const config = require('./config');
const logger = require('./logger');

let redisClient = null;

/**
 * 创建Redis客户端
 * @returns {Promise<*>} Redis客户端
 */
const createClient = async () => {
  try {
    if (!redisClient) {
      const client = redis.createClient({
        url: `redis://${config.redis.host}:${config.redis.port}`,
        password: config.redis.password,
      });

      client.on('error', (err) => logger.error('Redis错误:', err));
      client.on('connect', () => logger.info('已连接到Redis'));
      client.on('reconnecting', () => logger.info('正在重新连接到Redis'));
      client.on('ready', () => logger.info('Redis已就绪并可使用'));

      await client.connect();
      redisClient = client;
    }
    return redisClient;
  } catch (error) {
    logger.error('Redis连接失败:', error);
    throw error;
  }
};

/**
 * 获取Redis客户端实例
 * @returns {Promise<*>} Redis客户端
 */
const getClient = async () => {
  if (!redisClient) {
    return createClient();
  }
  return redisClient;
};

/**
 * 设置Redis键值对
 * @param {string} key - 键
 * @param {string} value - 值
 * @param {number} expiry - 过期时间（秒）
 * @returns {Promise<void>}
 */
const set = async (key, value, expiry = null) => {
  try {
    const client = await getClient();
    if (expiry) {
      await client.set(key, value, { EX: expiry });
    } else {
      await client.set(key, value);
    }
  } catch (error) {
    logger.error(`Redis设置键失败: ${key}`, error);
    throw error;
  }
};

/**
 * 获取Redis键的值
 * @param {string} key - 键
 * @returns {Promise<string>} 值
 */
const get = async (key) => {
  try {
    const client = await getClient();
    return await client.get(key);
  } catch (error) {
    logger.error(`Redis获取键失败: ${key}`, error);
    throw error;
  }
};

/**
 * 删除Redis键
 * @param {string} key - 键
 * @returns {Promise<number>} 删除的键数量
 */
const del = async (key) => {
  try {
    const client = await getClient();
    return await client.del(key);
  } catch (error) {
    logger.error(`Redis删除键失败: ${key}`, error);
    throw error;
  }
};

module.exports = {
  createClient,
  getClient,
  set,
  get,
  del,
}; 